Defining a Model

This section demonstrates the model definition process.

Model Definition Overview

The overall procedure for defining the elements of a model can be broken down into the following steps:

  • Set active levels

  • Define components

  • Execute pre-processing methods

The model can be visualized at any step in the process to confirm its validity.

To see all the available arguments of each of the following methods, please read the API reference or their docstrings.

Alternatively, use the help() function inside a python shell. e.g. help(mdl.add_level)

You can also use pydoc <osmg.name_of_module> in a terminal window.

[1]:
# imports
import numpy as np
from osmg import model
import osmg.defaults as defaults
from osmg.gen.section_gen import SectionGenerator
from osmg.ops.section import ElasticSection
from osmg.gen.component_gen import BeamColumnGenerator
from osmg.ops.element import ElasticBeamColumn
from osmg.graphics.preprocessing_3d import show
[2]:
# Instantiate a model
mdl = model.Model('example_model')
[3]:
help(mdl.add_level)
Help on method add_level in module osmg.model:

add_level(uid: 'int', elevation: 'float') -> 'None' method of osmg.model.Model instance
    Adds a level to the model.

    Arguments:
        uid: Unique ID for the level.
        elevation: Elevation of the level.

    Example:
        >>> from osmg.model import Model
        >>> model = Model('test_model')
        >>> model.add_level(1, 0.0)
        >>> model.levels.__srepr__()
        '[Collection of 1 items]'

[4]:
# Define levels
for i in range(3):
    mdl.add_level(i, 144.00*(i))
[5]:
defaults.load_default_steel(mdl)
steel_phys_mat = mdl.physical_materials.retrieve_by_attr(
    'name', 'default steel')
[6]:
# define line element sections
secg = SectionGenerator(mdl)
secg.load_aisc_from_database(
    'W',
    ["W24X94"],
    'default steel',
    'default steel',
    ElasticSection)
[6]:
{}
[7]:
# set active levels
mdl.levels.set_active([1, 2])
[8]:
p1 = np.array((0.00, 0.00))
p2 = np.array((360., 0.00))
p3 = np.array((360., 360.))
p4 = np.array((0.00, 360.00))
[9]:
mcg = BeamColumnGenerator(mdl)
sec = mdl.elastic_sections.retrieve_by_attr('name', 'W24X94')
for pt in [p1, p2, p3, p4]:
    mcg.add_vertical_active(
        x_coord=pt[0], y_coord=pt[1],
        offset_i=np.zeros(3), offset_j=np.zeros(3),
        transf_type='Corotational',
        n_sub=4,
        section=sec,
        element_type=ElasticBeamColumn,
        placement='centroid',
        angle=0.00)
[10]:
for pair in ((p1, p2), (p2, p3), (p3, p4), (p4, p1)):
    mcg.add_horizontal_active(
        xi_coord=pair[0][0],
        yi_coord=pair[0][1],
        xj_coord=pair[1][0],
        yj_coord=pair[1][1],
        offset_i=np.zeros(3),
        offset_j=np.zeros(3),
        snap_i='centroid',
        snap_j='centroid',
        transf_type='Linear',
        n_sub=4,
        section=sec,
        element_type=ElasticBeamColumn,
        placement='top_center',
        angle=0.00)
[11]:
show(mdl)
[12]:
# fixing the base
for node in mdl.levels[0].nodes.values():
    node.restraint = [True, True, True, False, False, False]
[13]:
show(mdl)

Preprocessing

Now that all the intended elements have been defined, we can apply pre-processing methods to the model.

Some common methods are the following:

  • rigid_diaphragms assigns rigid diaphragm constraints to all specified levels. Only primary nodes are affected (not internal nodes of component assemblies).

  • self_weight, self_mass assign self-weight loads and lumped self-mass to all the elements / nodes.

Loads, mass, and diaphragm constraints are load_case-specific.

[14]:
# imports
from osmg.load_case import LoadCase
from osmg.preprocessing.self_weight_mass import self_weight
from osmg.preprocessing.self_weight_mass import self_mass
[15]:
testcase = LoadCase('test', mdl)
[16]:
self_weight(mdl, testcase)
self_mass(mdl, testcase)
[17]:
testcase.rigid_diaphragms([1, 2])
[18]:
# visualize the model
show(mdl, testcase, extrude=True)